package cn.chinaflame.pagodas.service;

import cn.chinaflame.pagodas.Result.Result;
import cn.chinaflame.pagodas.constant.Sysconst;
import cn.chinaflame.pagodas.dto.PaProductDto;
import cn.chinaflame.pagodas.dto.ProductTypeDto;
import cn.chinaflame.pagodas.entity.PaProduct;
import cn.chinaflame.pagodas.entity.YwProductType;
import cn.chinaflame.pagodas.enums.CodeEnum;
import cn.chinaflame.pagodas.repository.PaProductRepository;
import cn.chinaflame.pagodas.repository.YwProductTypeRepository;
import cn.chinaflame.pagodas.req.YwProductTypeReq;
import cn.chinaflame.pagodas.utils.DateTimes;
import cn.chinaflame.pagodas.utils.Jackson;
import cn.chinaflame.pagodas.utils.ParamPreconditions;
import cn.chinaflame.pagodas.utils.TypeRef;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Map;

/**
 * @author wwt
 * @date 2018年1月4日 下午6:00:37
 */
@Service
public class YwProductTypeService {
    private final static Logger log = LoggerFactory.getLogger(YwProductTypeService.class);
    @Autowired
    private YwProductTypeRepository ywProductTypeRepository;
    @Autowired
    private IdGeneratorService idGeneratorService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private PaProductService paProductService;
    @Autowired
    private PaAgentService paAgentService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private PaProductRepository paProductRepository;

    @Transactional
    public ProductTypeDto add(Map<String, Object> val) {
        log.info("商品类别添加【service】map:{}", val);
		/*ParamPreconditions.checkNotEmpty(data, CodeEnum.FAIL.getCode(), "入参为空");
		Map<String, String> val = Jackson.readJson(data, new TypeRef<Map<String, String>>());*/
		//判断参数是否为空
		boolean b = !"".equals(val.get("name")) || null != val.get("name");
		ParamPreconditions.checkArgument(b, CodeEnum.FAIL.getCode(), "name为空");
		boolean bb = !"".equals(val.get("itemId")) || null != val.get("itemId");
		ParamPreconditions.checkArgument(bb, CodeEnum.FAIL.getCode(), "itemId为空");
		YwProductType yptype = new YwProductType();
	    yptype.setId(idGeneratorService.generateIdByTableName("yw_product_type"));
		yptype.setName(String.valueOf(val.get("name")));
		yptype.setItemId(String.valueOf(val.get("itemId")));
		yptype.setProjectId(String.valueOf(val.get("projectId")));
		yptype.setState(Sysconst.ENABLED_TRUE);
		yptype.setCreatetime(DateTimes.nowDateTime());
		yptype.setUpdatetime(DateTimes.nowDateTime());
		ywProductTypeRepository.saveAndFlush(yptype);
		ProductTypeDto dto = new ProductTypeDto();
		BeanUtils.copyProperties(yptype, dto);
		return dto;
	}
	
	public ProductTypeDto update (String data) {
		log.info("商品类别修改【service】data:{}",data);
		ParamPreconditions.checkNotEmpty(data, CodeEnum.FAIL.getCode(), "入参为空");
		Map<String, String> val = Jackson.readJson(data, new TypeRef<Map<String, String>>());
		//判断参数是否为空
		boolean b = !"".equals(val.get("id")) || null != val.get("id");
		ParamPreconditions.checkArgument(b, CodeEnum.FAIL.getCode(), "id为空");
		boolean bb = !"".equals(val.get("name")) || null != val.get("name");
		ParamPreconditions.checkArgument(bb, CodeEnum.FAIL.getCode(), "name为空");
		YwProductType yptype =ywProductTypeRepository.findOne(val.get("id"));
		yptype.setName(val.get("name"));
		yptype.setItemId(val.get("itemId"));
		yptype.setProjectId(val.get("projectId"));
		yptype.setUpdatetime(DateTimes.nowDateTime());
		ywProductTypeRepository.save(yptype);
		ProductTypeDto dto = new ProductTypeDto();
		BeanUtils.copyProperties(yptype, dto);
		return dto;
	}
	
	public boolean delete (String id) {
		log.info("商品类别删除【service】id:{}",id);
		ParamPreconditions.checkNotEmpty(id, CodeEnum.FAIL.getCode(), "入参为空");
		List<PaProductDto> list = paProductService.query(null, null, null, null, null, id, null, null, null, null,null);
		ParamPreconditions.checkArgument(list == null || list.size() == 0, CodeEnum.FAIL.getCode(), "商品绑定该类别，不能删除");
		YwProductType productType = ywProductTypeRepository.findOne(id);
		if(productType == null) return true;
		productType.setState(Sysconst.ENABLED_FALSE);
		ywProductTypeRepository.saveAndFlush(productType);
		return true;
	}
	public boolean delete2(String id){
		log.info("商品类别删除【service】id:{}",id);
		ParamPreconditions.checkNotEmpty(id, CodeEnum.FAIL.getCode(), "入参为空");
		List<PaProduct> products = paProductRepository.findByProductTypeId(id);
		ParamPreconditions.checkArgument(products==null || products.size()==0,CodeEnum.FAIL.getCode(),"商品绑定该类别，不能删除");
		YwProductType productType = ywProductTypeRepository.getOne(id);
		productType.setState(Sysconst.ENABLED_FALSE);
		ywProductTypeRepository.saveAndFlush(productType);
		return true;
	}
	
	
	
	
	/**
	 * 
	 * @param pageIndex		页码
	 * @param pageSize		页数
	 * @param id			商品类别ID
	 * @param name			商品类别名称
	 * @return
	 */
	public List<ProductTypeDto> query (Integer pageIndex, Integer pageSize, String id, String name, String itemId, String projectId) {
		log.info("商品类别查询【service】pageIndex:{}, pageSize:{}, item_id:{}, name:{}, itemId:{}, projectId:{}",pageIndex,
				pageSize, id, name, itemId, projectId);
		if(commonService.paginationSupport(pageIndex, pageSize)) {
			return queryByPage1(pageIndex, pageSize, id, name, itemId, projectId);
		}
		List<YwProductType> productTypeList = ywProductTypeRepository.findAll(new Specification<YwProductType>() {
			@Override
			public Predicate toPredicate(Root<YwProductType> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = Lists.newArrayList();
				list.add(cb.equal(root.get("state").as(String.class), Sysconst.ENABLED_TRUE));
				if(!Strings.isNullOrEmpty(name)) {
					list.add(cb.equal(root.get("name").as(String.class), name));
				}					
				if(!Strings.isNullOrEmpty(itemId)) {
					list.add(cb.equal(root.get("itemId").as(String.class), itemId));
				}
				if(!Strings.isNullOrEmpty(projectId)) {
					list.add(cb.equal(root.get("projectId").as(String.class), projectId));
				}
				if(!Strings.isNullOrEmpty(id)) {
					list.add(cb.equal(root.get("id").as(String.class), id));
				}					
				Predicate[] p = new Predicate[list.size()];
				return cb.and(list.toArray(p));
			}
		});
		List<ProductTypeDto> dtoList = Lists.newArrayList();
		for(YwProductType item : productTypeList) {
			ProductTypeDto dto = new ProductTypeDto();
			BeanUtils.copyProperties(item, dto);
			dtoList.add(dto);
		}
		return dtoList;
	}
	
	
	/**
	 * 
	 * @param pageIndex		页码
	 * @param pageSize		页数
	 * @param id			商品类别ID
	 * @param name			商品类别名u
	 * @return
	 */
	public List<ProductTypeDto> queryByPage1 (Integer pageIndex, Integer pageSize, String id, String name, String itemId, String projectId) {
		log.info("商品类别查询【service】pageIndex:{}, pageSize:{}, item_id:{}, name:{}, itemId:{}, projectId:{}",pageIndex,
				pageSize, id, name, itemId, projectId);
		Pageable p = new PageRequest(pageIndex-1, pageSize, new Sort(Direction.DESC, "updatetime"));
		Page<YwProductType> entityList = ywProductTypeRepository.findAll(new Specification<YwProductType>() {
			@Override
			public Predicate toPredicate(Root<YwProductType> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				List<Predicate> list = Lists.newArrayList();
				list.add(cb.equal(root.get("state").as(String.class), Sysconst.ENABLED_TRUE));
				if(!Strings.isNullOrEmpty(name)) {
					list.add(cb.equal(root.get("name").as(String.class), name));
				}					
				if(!Strings.isNullOrEmpty(itemId)) {
					list.add(cb.equal(root.get("itemId").as(String.class), itemId));
				}
				if(!Strings.isNullOrEmpty(projectId)) {
					list.add(cb.equal(root.get("projectId").as(String.class), projectId));
				}
				if(!Strings.isNullOrEmpty(id)) {
					list.add(cb.equal(root.get("id").as(String.class), id));
				}					
				Predicate[] p = new Predicate[list.size()];
				return cb.and(list.toArray(p));
			}
		}, p);
		List<YwProductType> itemList = entityList.getContent();
		List<ProductTypeDto> dtoList = Lists.newArrayList();
		for(YwProductType item : itemList) {
			ProductTypeDto dto = new ProductTypeDto();
			BeanUtils.copyProperties(item, dto);
			dtoList.add(dto);
		}
		return dtoList;
	}
	
	
	public Result<List<ProductTypeDto>> queryByPage(YwProductTypeReq req) {
		log.info("商品类别查询【service】req{}",req);
//		String str = paAgentService.queryAryId(req.getAgentId());
		String sql = "select "
				+ "ypt.id as id,"
				+ "ypt.name as name,"
				+ "ypt.item_id as itemId,"
				+ "ypt.project_id as projectId,"
				+ "ypt.createtime as createtime,"
				+ "ypt.updatetime as updatetime "
				+ "from yw_product_type ypt inner join "
				+ "yw_item yi on (ypt.item_id = yi.id) where 1=1 and ypt.state=0 ";
		StringBuilder sb = new StringBuilder();
		if(!Strings.isNullOrEmpty(req.getItemId())){
			sb.append(" and ypt.item_id = ").append(req.getItemId());
		}
		if(!Strings.isNullOrEmpty(req.getId())){
			sb.append(" and ypt.id = ").append(req.getId());
		}
//		sb.append("and yi.agent_id in ("+str+")");
		sb.append("ORDER BY ypt.createtime DESC");

		JdbcPage<ProductTypeDto> page = new JdbcPage<>(sql + sb.toString(), req.getPageSize(), req.getPageIndex(), jdbcTemplate, ProductTypeDto.class);
		return Result.createPage(page.getPage(),req.getPageSize(), req.getPageIndex(), page.getCount());
	}

}
